package service

import (
	sqlc "bgs/db/sqlc"
	"bgs/grpc/gen/proxy2/wxpay"
	"bgs/service/model"
	"encoding/json"
)

type FilterLedgerRequestFunc func(sqlc.LedgerRequest) bool
type FilterLedgerRequestPtrFunc func(*sqlc.LedgerRequest) bool
type FilterLedgerDetailPtrFunc func(*sqlc.LedgerDetail) bool

func (s *LedgerServiceImp) ConvLedgerDetailPtrsToIDs(ptrs []*sqlc.LedgerDetail) (ids []int64) {
	for _, ptr := range ptrs {
		ids = append(ids, ptr.ID)
	}
	return
}

func (s *LedgerServiceImp) ConvLedgerDetailEntitiesToPtrs(in []sqlc.LedgerDetail) []*sqlc.LedgerDetail {
	out := make([]*sqlc.LedgerDetail, len(in))
	for i := range in {
		out[i] = &in[i]
	}
	return out
}

func (s *LedgerServiceImp) ConvLedgerRequestEntitiesToPtrs(in []sqlc.LedgerRequest) []*sqlc.LedgerRequest {
	out := make([]*sqlc.LedgerRequest, len(in))
	for i := range in {
		out[i] = &in[i]
	}
	return out
}

func (s *LedgerServiceImp) ConvLedgerDetailPtrToProfitReceiverPtr(in *sqlc.LedgerDetail) (out *wxpay.ProfitReceiver) {
	receiverPtr := &model.ProfitReceiver{}
	json.Unmarshal(in.Receiver, receiverPtr)
	out = &wxpay.ProfitReceiver{Type: receiverPtr.Type, ReceiverAccount: receiverPtr.Account, Amount: in.Amount, Description: in.Remark.String}
	return
}

func (s *LedgerServiceImp) ConvLedgerDetailPtrsToProfitReceiverPtrs(in []*sqlc.LedgerDetail) (out []*wxpay.ProfitReceiver) {
	for _, ptr := range in {
		out = append(out, s.ConvLedgerDetailPtrToProfitReceiverPtr(ptr))
	}
	return
}

func (s *LedgerServiceImp) FilterLedgerRequests(in []sqlc.LedgerRequest, f FilterLedgerRequestFunc) (out []sqlc.LedgerRequest) {
	for _, ptr := range in {
		if f(ptr) {
			out = append(out, ptr)
		}
	}
	return
}

func (s *LedgerServiceImp) FindLedgerRequest(in []sqlc.LedgerRequest, f FilterLedgerRequestPtrFunc) (out *sqlc.LedgerRequest, ok bool) {
	for i := range in {
		ptr := &in[i]
		if f(ptr) {
			out = ptr
			ok = true
			break
		}
	}
	return
}

// FilterLedgerDetailPtrs []*sqlc.LedgerDetail => []*sqlc.LedgerDetail
func (s *LedgerServiceImp) FilterLedgerDetailPtrs(in []*sqlc.LedgerDetail, f FilterLedgerDetailPtrFunc) (out []*sqlc.LedgerDetail) {
	for _, ptr := range in {
		if f(ptr) {
			out = append(out, ptr)
		}
	}
	return
}

// FilterLedgerDetailPtrs []*sqlc.LedgerDetail => []*sqlc.LedgerDetail
func (s *LedgerServiceImp) FindLedgerDetailPtr(in []*sqlc.LedgerDetail, f FilterLedgerDetailPtrFunc) (out *sqlc.LedgerDetail, ok bool) {
	for _, ptr := range in {
		if f(ptr) {
			out = ptr
			ok = true
			break
		}
	}
	return
}

// SplitLedgerDetails  []*sqlc.LedgerDetail => truePart []*sqlc.LedgerDetail, falsePart []*sqlc.LedgerDetail
func (s *LedgerServiceImp) SplitLedgerDetails(ptrs []*sqlc.LedgerDetail, f FilterLedgerDetailPtrFunc) (truePart []*sqlc.LedgerDetail, falsePart []*sqlc.LedgerDetail) {
	if len(ptrs) == 0 {
		return
	}
	for _, ptr := range ptrs {
		if f(ptr) {
			truePart = append(truePart, ptr)
		} else {
			falsePart = append(falsePart, ptr)
		}
	}
	return
}
